﻿using System;

namespace Asistente.Model.IFPUG.MeasureUtilities
{
    //Clase que conoce las tablas de IFPUG, sabe retornar la complejidad asociada
    // a una funcion de datos o funcion de transaccion dada la cantidad de 
    // DETS RETS FTRS segun corresponda.

    public class IfpugMeasureManager
    {
        private static IfpugMeasureManager _instance;
        private static int[,] Eif { get; set; }
        private static int[,] Ilf { get; set; }
        private static int[,] EiEq { get; set; }
        private static int[,] Eo { get; set; }

        #region Creacion de Representacion

        public static IfpugMeasureManager Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new IfpugMeasureManager();
                    // Data function matrix initialization
                    Ilf = new[,] { { 7, 7, 10 }, { 7, 10, 15 }, { 10, 15, 15 } };
                    Eif = new[,] { { 5, 5, 7 }, { 5, 7, 10 }, { 7, 10, 10 } };

                    // Transactional function matrix initialization
                    Eo = new[,] { { 4, 4, 5 }, { 4, 5, 7 }, { 5, 7, 7 } };
                    EiEq = new[,] { { 3, 3, 4 }, { 3, 4, 6 }, { 4, 6, 6 } };
                   
                } 
                return _instance;
            }
        }

        #endregion

        #region Funciones de datos

        public int DataFunctionMeasure(int rowValue, int columnValue,
                                            int menCol, int medCol,
                                            int menRow, int medRow, DataFunctionType dataFunctionType)
        {
            int rowIndex;
            int columnIndex;

            //ROW
            if (rowValue < menRow)
            { rowIndex = 0; }
            else if (menRow <= rowValue && rowValue < medRow)
            { rowIndex = 1; }
            else { rowIndex = 2; }

            //DET: COLUMN
            if (columnValue < menCol)
            { columnIndex = 0; }
            else if (menCol <= columnValue && columnValue < medCol)
            { columnIndex = 1; }
            else { columnIndex = 2; }

            switch (dataFunctionType)
            {
                case DataFunctionType.Eif:
                    return Eif[rowIndex, columnIndex];
                case DataFunctionType.Ilf:
                    return Ilf[rowIndex, columnIndex];
                default:
                    throw new NotImplementedException();
            }            
        }


        public int IlfMeasure(int detValue, int retValue) 
        {
            return DataFunctionMeasure(retValue, detValue, 20, 51, 2, 6, DataFunctionType.Ilf);
        }

        public int EifMeasure(int detValue, int retValue)
        {
            return DataFunctionMeasure(retValue, detValue, 20, 51, 2, 6, DataFunctionType.Eif);
        }

        #endregion 

        #region Funciones de transaccion

        public int TransactionalFunctionMeasure(int rowValue, int columnValue,
                                            int menCol, int medCol,
                                            int menRow, int medRow, TransactionalFunctionType transactionalFunctionType)
        {
            int rowIndex;
            int columnIndex;

            //ROW
            if (rowValue < menRow)
            { rowIndex = 0; }
            else if (menRow <= rowValue && rowValue < medRow)
            { rowIndex = 1; }
            else { rowIndex = 2; }

            //DET: COLUMN
            if (columnValue < menCol)
            { columnIndex = 0; }
            else if (menCol <= columnValue && columnValue < medCol)
            { columnIndex = 1; }
            else { columnIndex = 2; }

            switch (transactionalFunctionType)
            {
                case TransactionalFunctionType.Ei:
                    return EiEq[rowIndex, columnIndex];
                case TransactionalFunctionType.Eo:
                    return Eo[rowIndex, columnIndex];
                case TransactionalFunctionType.Eq:
                    return EiEq[rowIndex, columnIndex];
            }
            throw new NotImplementedException();
        }
    

        public int EiMeasure(int detValue, int ftrValue)
        {
            return TransactionalFunctionMeasure(ftrValue, detValue, 5, 16, 2, 3, TransactionalFunctionType.Ei);
        }

        public int EoMeasure(int detValue, int ftrValue)
        {
            return TransactionalFunctionMeasure(ftrValue, detValue, 6, 20, 2, 4, TransactionalFunctionType.Eo);
        }

        public int EqMeasure(int detValue, int ftrValue)
        {
            return TransactionalFunctionMeasure(ftrValue, detValue, 6, 20, 2, 4, TransactionalFunctionType.Eq);
        }
        
        #endregion       
        
    }
}
